import numpy as np
import matplotlib.pyplot as plt
from sklearn.decomposition import PCA
from sklearn.datasets import make_classification
from sklearn.preprocessing import StandardScaler

# 设置中文字体
plt.rcParams['font.sans-serif'] = ['SimHei']  # 使用黑体
plt.rcParams['axes.unicode_minus'] = False  # 解决负号显示问题
# 'Microsoft YaHei' (微软雅黑)
# 'KaiTi' (楷体)
# 'FangSong' (仿宋)
# 'STSong' (宋体)

def visualize_pca():
    # Generate synthetic data
    X, y = make_classification(
        n_samples=1000,
        n_features=20,
        n_informative=5,
        n_redundant=5,
        n_classes=10,
        random_state=42
    )

    # Standardize data
    scaler = StandardScaler()
    X_scaled = scaler.fit_transform(X)

    # Perform PCA
    pca = PCA(n_components=2)
    X_pca = pca.fit_transform(X_scaled)

    # Create figure with subplots
    fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(16, 6))

    # Scatter plot of PCA results
    scatter = ax1.scatter(
        X_pca[:, 0],
        X_pca[:, 1],
        c=y,
        cmap='viridis',
        alpha=0.7
    )
    ax1.set_title('PCA降维可视化 (二维投影)')
    ax1.set_xlabel(f'第一主成分 PC1 (方差解释率: {pca.explained_variance_ratio_[0]*100:.1f}%)')
    ax1.set_ylabel(f'第二主成分 PC2 (方差解释率: {pca.explained_variance_ratio_[1]*100:.1f}%)')
    ax1.grid(True, alpha=0.3)

    # Variance explained plot
    ax2.bar(
        range(len(pca.explained_variance_ratio_)),
        pca.explained_variance_ratio_,
        alpha=0.7,
        label='各主成分方差解释率'
    )
    ax2.plot(
        np.cumsum(pca.explained_variance_ratio_),
        'r-o',
        label='累计方差解释率'
    )
    ax2.set_title('主成分方差解释率')
    ax2.set_xlabel('主成分')
    ax2.set_ylabel('方差解释率')
    ax2.legend()
    ax2.grid(True, alpha=0.3)

    # Add colorbar and adjust layout
    plt.colorbar(scatter, ax=ax1, label='类别')
    plt.tight_layout()
    plt.show()

    # Print key information
    print("\nPCA Analysis Results:")
    print(f"Explained variance ratio: {pca.explained_variance_ratio_}")
    print(f"Total explained variance: {np.sum(pca.explained_variance_ratio_):.3f}")
    print(f"Principal components shape: {pca.components_.shape}")

if __name__ == "__main__":
    visualize_pca()
